﻿using System;
using System.Collections.Generic;
using System.Linq;
using Elasticsearch.Net;
using EP.Base.BaseService.Manager.Interface;
using EP.Base.BaseService.Manager.Model;
using Nest;

namespace EP.Base.BaseService.Manager.EsSystemData
{
    public class EsData : IEsData
    {
        /// <summary>
        /// 根据别名获取所有关联索引
        /// </summary>
        /// <param name="esHosts"></param>
        /// <param name="alias"></param>
        /// <returns></returns>
        [Obsolete("该仅能使用别名获取，已新加方法 GetAllIndexByIndexPreFixOrAlias() ")]
        public string[] GetAllIndexByAlias(IEnumerable<string> esHosts, string alias)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(alias))
                return null;

            var client = CreateClient(esHosts);
            var result = client.GetAlias(a => a.Name(alias));
            if(result!=null && result.Indices!=null)
                return result.Indices.Select(index => index.Key).ToArray();
            return null;
        }
        /// <summary>
        /// 根据索引前缀或别名获取所有关联索引
        /// </summary>
        /// <param name="esHosts"></param>
        /// <param name="indexPreOrAlias">索引前缀（indexname-*）或别名（indexalias）</param>
        /// <returns></returns>
        public string[] GetAllIndexByIndexPreFixOrAlias(IEnumerable<string> esHosts, string indexPreOrAlias)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(indexPreOrAlias))
                return null;

            var client = CreateClient(esHosts);
            var result = client.GetAlias(a => a.Index(indexPreOrAlias));
            if (result != null && result.Indices != null)
                return result.Indices.Select(index => index.Key).ToArray();
            return null;
        }
        public bool DeleteIndex(IEnumerable<string> esHosts, string indexName)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(indexName) )
                return false;

            var client = CreateClient(esHosts);
            var result=client.DeleteIndex(indexName);
            if (result.ServerError == null)
                return true;
            return false;
        }

        /// <summary>
        /// 创建esclient
        /// </summary>
        /// <param name="esHosts"></param>
        /// <returns></returns>
        private IElasticClient CreateClient(IEnumerable<string> esHosts)
        {
            var enumerable = esHosts as string[] ?? esHosts.ToArray();
            if(esHosts==null || !enumerable.Any())
                throw new ArgumentNullException("esHosts");
            
            //多node
            var nodes = enumerable.Select(n => new Node(new Uri("http://"+n)));
            var pool = new StaticConnectionPool(nodes);
 
            var settings = new ConnectionSettings(pool).DefaultFieldNameInferrer(n=>n);
 
            return new ElasticClient(settings);
        }
        /// <summary>
        /// 快照多个索引
        /// </summary>
        /// <param name="esHosts"></param>
        /// <param name="repository"></param>
        /// <param name="snapshotName"></param>
        /// <param name="index"></param>
        public bool Snapshot(IEnumerable<string> esHosts, string repository, string snapshotName, IEnumerable<string> index)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(repository) || string.IsNullOrWhiteSpace(snapshotName) || index == null ||
                !index.Any())
                return false;

            var client = CreateClient(esHosts);

            Indices indices = Indices.Index(index.Select(n => (IndexName) n));
            
            var result= client.Snapshot(repository, snapshotName, sp => sp.Indices(indices));
            
            if(result.ServerError==null)
                return true;
            throw new Exception(result.ServerError.ToString());
        }

        public bool DeleteSnapshot(IEnumerable<string> esHosts, string repository, string snapshotName)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(repository) || string.IsNullOrWhiteSpace(snapshotName))
                return false;
            var client = CreateClient(esHosts);
            var result = client.DeleteSnapshot(repository, snapshotName);
            if (result.ServerError == null)
                return true;
            throw new Exception(result.ServerError.ToString());
        }

        public EsSnapshotInfo GetSnapshotInfo(IEnumerable<string> esHosts, string repository, string snapshotName)
        {
            if (esHosts == null || !esHosts.Any() || string.IsNullOrWhiteSpace(repository) || string.IsNullOrWhiteSpace(snapshotName))
                return null;
            var client = CreateClient(esHosts);
            var result = client.GetSnapshot(repository, snapshotName);
            if (result.ServerError == null)
            {
                var sh = result.Snapshots.FirstOrDefault();
                if (sh == null || string.IsNullOrWhiteSpace(sh.Name))
                    return null;
                return new EsSnapshotInfo() {Name = sh.Name,State = sh.State};
            }
            throw new Exception(result.ServerError.ToString());
        }
    }
}
